import UserManager from './UserManager';
import Api from '../service/Api';
import Session from '../service/Session';
import JsBridge from '../service/JsBridge';

class ChatManager {
    constructor() {
        this.userInfo = Session.getUser();
        this.MaxNumUpdateLog_ID = 0;
        this.MaxMessageLog_ID = 0;
        this.MaxMessage_ID = 0;
        this.MaxBellLog_ID = 0;

        this._discussGroups = null;
        this._sysMessages = [];
        this._messages = [];
        this._onMessage = $.Callbacks();
        this._onSysMessage = $.Callbacks();
        this._onMessageRemove = $.Callbacks();
        this._onPoll = $.Callbacks();
        this.refreshUser = this.refreshUser.bind(this);

        this.ClientCode = '';
        this.ClientMessage_ID = 0;

        this._polling = false;
        this._lastPoll = null;
        this._messageUpdate = false;

        this._genMessage = this._genMessage.bind(this);
    }

    getLastPoll() {
        return this._lastPoll;
    }

    getMessageUpdate() {
        return this._messageUpdate;
    }

    refreshUser() {
    	this.userInfo = Session.getUser(true);
    }

    _getDiscussGroups() {
        let deferred = $.Deferred();

        if (this._discussGroups === null) {
            Api.get('/BasePlate/Interface/IInterfaceJson.asmx/DiscussGroup_GetList', {
                User_ID: this.userInfo.User_ID,
                SessionID: this.userInfo.SessionID,
                Unit_ID: this.userInfo.Unit_ID
            }).then(function (resp) {
                this._discussGroups = resp.Goodo.R;
                deferred.resolve(this._discussGroups);
            });
        } else {
            deferred.resolve(this._discussGroups);
        }

        return deferred;
    }

    _lookupUserOrDiscussGroup(userId) {
        let deferred = $.Deferred();

        if (userId < 0) {
            this._getDiscussGroups().then(discusssGroups => {
                if (discusssGroups) {

                    let index = discusssGroups.indexOf(userId);
                    for (let i = 0; i < discusssGroups.length; i++) {
                      if ( -discusssGroups[i].Group_ID == userId) {
                        deferred.resolve(discusssGroups[i]);
                        break;
                      }
                    }

                }
            });
        } else {
            UserManager.queryUser(userId).then(u => {
                deferred.resolve(u);
            });
        }

        return deferred;
    }

    flushDiscussGroups() {
        this._discussGroups = null;

        for (let k in this._messages) {
            if (this._messages[k].id < 0) {
                this._messages[k].user = null;
            }
        }
    }

    notifyMessage(userId) {
        if (this._messages[userId]) {
            let m = this._messages[userId];
            if (! m.user) {
                this._lookupUserOrDiscussGroup(userId).then(u => {
                    m.user = u;
                    this._notifyMessage(m);
                });
            } else {
                this._notifyMessage(m);
            }
        }
    }

    getMessage(userId) {
        let deferred = $.Deferred();

        if (this._messages[userId]) {
            this._lookupUserOrDiscussGroup(userId).then(u => {

                this._messages[userId].user = u;

                JsBridge.sendRequest("message.byuser", {
                    LoginID: this.userInfo.User_ID,
                    user: u.User_ID,
                    group: u.Group_ID
                }).then(resp => {

                    let xhrs = resp.data.map(m => {
                        m.ts = moment(m.SendDate).unix();

                        if (m.Send_ID != '0') {
                            return UserManager.queryUser(m.Send_ID < 0 ? m.Send_ID2 : m.Send_ID).then(sender => {
                                m.sender = sender;
                            });
                        } else {
                            return true;
                        }
                    });

                    $.when.apply($, xhrs).then(() => {
                        this._messages[userId].messages = resp.data;
                        this._messages[userId].messages.sort((a, b) => {
                            return a.ts - b.ts;
                        });
                        deferred.resolve(this._messages[userId]);
                    });
                });

            });
        } else {
        	
            this._lookupUserOrDiscussGroup(userId).then(u => {
                deferred.resolve({ id: userId, user: u, date: null, message: null, messages: [] });
            });
        }

        return deferred;
    }

    removeMessage(userId) {
        let m = this._messages[userId];

        if (m) {
            this._onMessageRemove.fireWith(this, [m, this._messages]);
        }
    }

    onSysMessage(cb) {
        this._onSysMessage.add(cb);
    }

    onMessage(cb) {
        this._onMessage.add(cb);
    }

    onMessageRemove(cb) {
        this._onMessageRemove.add(cb);
    }

    onPoll(cb) {
        this._onPoll.add(cb);
    }

    getAllSysMessage() {
        return this._sysMessages.concat([]);
    }

    getSysMessage(id) {
        return this._sysMessages[id];
    }

    _notifyMessage(m) {
        this._onMessage.fireWith(this, [m, this._messages]);
    }

    _notifySysMessage(m) {
        this._onSysMessage.fireWith(this, [m, this._sysMessages]);
    }

    _processSysMessage(m) {
        if (! this._sysMessages[m.Send_ID2]) this._sysMessages[m.Send_ID2] = {id: m.Send_ID2, date: null, message: null, messages: []};

        let _m = this._sysMessages[m.Send_ID2];
        _m.message = m;
        _m.date = m.SendDate;
        _m.ts = moment(m.SendDate).unix();

        _m.messages.push(m);

        return _m;
    }

    _addMessage(m) {
        let id = null, deferred = $.Deferred();

        if (m.Send_ID == this.userInfo.User_ID) id = m.Receive_ID;
        else id = m.Send_ID;
console.log(m.ClientMessage_ID+'------m.ClientMessage_ID')
        if (id !== null) {
            if (! this._messages[id]) this._messages[id] = { id: id, user: null, ts: null, date: null, message: null, messages: []}

            let _m = this._messages[id], wait = false;

            if (m.Send_ID != '0') {
                wait = UserManager.queryUser(m.Send_ID < 0 ? m.Send_ID2 : m.Send_ID).then(sender => {
                    m.sender = sender;
                });
            } else {
                wait = true;
            }

            $.when(wait).then(result => {
                const ts = moment(m.SendDate).unix() || 0;

                m.ts = ts;
                // 判断此m是否为新消息
                let index = null;
                for (let i = 0; i < _m.messages.length; i++) {
                  // 通过ClientMessage_ID， ClientCode来判断是否是已存在的消息
                  if (_m.messages[i].ClientCode == m.ClientCode && _m.messages[i].ClientMessage_ID == m.ClientMessage_ID) {
                    index = i;
                    break;
                  }
                }
                if (index !== null) { // 非新消息
                  // 更新消息
                  console.log('前一消息')
                  console.log(_m.messages[index])
                  console.log('后一消息')
                  console.log(m)
                  m = $.extend({}, _m.messages[index], m);
                  _m.messages[index] = m;
                } else { // 新消息
                  console.log('新消息')
                  console.log(m)
                  // 推入新消息
                  _m.messages.push(m);
                }
                _m.message = m;
                _m.date = m.SendDate;
                _m.ts = ts;

                console.log(`add message: ${m.SendName}=>${m.ReceiveName}`);
                console.log(m)
                console.log(_m);

                deferred.resolve(_m);
            });

        } else {
            deferred.reject();
        }

        return deferred;
    }

    pollMessage() {//轮询

        if (this._polling) {
            return false;
        }

        this._polling = true;
        return Api.get('/BasePlate/Interface/IInterfaceJson.asmx/Message_GetByMaxID2', {
            User_ID: this.userInfo.User_ID,
            SessionID: this.userInfo.SessionID,
            MaxMessage_ID: this.MaxMessage_ID,
            MaxMessageLog_ID: 31000,//this.MaxMessageLog_ID,
            MaxBellLog_ID: this.MaxBellLog_ID,
            MaxNumUpdateLog_ID: 0//this.MaxNumUpdateLog_ID
        }).then((resp) => {
console.log(resp)
            if (resp.Goodo.EID == 5) { // 无数据 不作处理
              this._polling = false;
              this._messageUpdate = true;
              $(".footer").find("ul").find("a").eq(2).find("span").css('display', 'none');
              $('.left .the-last').css('display', 'none');
              return false;
            }

            $(".footer").find("ul").find("a").eq(2).find("span").css('display', 'block');

            $('.left .nomessage').css('display', 'none');
            $('.left .the-last').css('display', 'block');

            if (this.MaxNumUpdateLog_ID) {
                this.MaxNumUpdateLog_ID = parseInt(resp.Goodo.MaxNumUpdateLog_ID);
            }
            this.MaxMessageLog_ID = parseInt(resp.Goodo.CurMaxMessageLog_ID);

            const LocalPath = window._LocalPath || {};
            console.log(`---------GM`)
            console.log(resp.Goodo.M)
            console.log(LocalPath)
            // 将文件类型添上存储的localpath
            resp.Goodo.M && resp.Goodo.M.forEach(item => {
              if (!item.LocalPath && LocalPath[`${item.ClientCode}-${item.ClientMessage_ID}`]) {
                item.LocalPath = LocalPath[`${item.ClientCode}-${item.ClientMessage_ID}`];
              }
            })

            this.processMessages(resp.Goodo.M, true);

            let messageStatusUpdate = [];

            resp.Goodo.ML && resp.Goodo.ML.forEach(item => {
                if (item.LogType == '1') { // 已读状态改变
                    messageStatusUpdate.push({Message_ID: item.Message_ID, IsRead: item.ToStat});
                    JsBridge.sendRequest("message.read", {ids: [item.Message_ID], status: item.ToStat});

                } else if (item.LogType == '2') { // 删除状态改变

                } else if (item.LogType == '3') { // 计数型系统消息数字变化

                } else if (item.LogType == '4') { // 因用户退出讨论组导致的用户发送的讨论组消息Send_ID变为-1

                }
            })

            //this.MaxMessage_ID = Math.max(parseInt(resp.Goodo.CurMaxMessage_ID) - 100, this.MaxMessage_ID);

            if (this.MaxMessage_ID == parseInt(resp.Goodo.CurMaxMessage_ID) && ! this._messageUpdate) {
                this.saveLocalMessages();
                this._messageUpdate = true;
            }

            this._lastPoll = new Date();
            this._polling = false;

            let MessageUnread = 0;
            resp.Goodo.MessageNum && resp.Goodo.MessageNum.forEach(x => {
              if (x.Send_ID != this.userInfo.User_ID) { // 过滤自己给自己发的消息
                MessageUnread += parseInt(x.Num)
              }
            });

            let SysMessageUnread = 0;
            resp.Goodo.NumUpdate && resp.Goodo.NumUpdate.forEach(x => {
                if (x.IsCount == "1" && x.Remind_ID != "9401") {
                    SysMessageUnread += parseInt(x.Num);
                }
            });

            this._onPoll.fireWith(this, [{ MessageUnread, SysMessageUnread,
                SysUpdate: resp.Goodo.NumUpdate,
                MessageUpdate: resp.Goodo.MessageNum,
                MessageStatusUpdate: messageStatusUpdate,
            }]);


            return true;
        });
    }

    processMessages(messages, addLocal) {
        messages && messages.forEach(item => {

            this.MaxMessage_ID = Math.max(parseInt(item.Message_ID), this.MaxMessage_ID);

            if (item.MsgType == 3) {
                console.log("image message");
            } else if (item.MsgType == 4) {
                console.log("voice message");
            } else if (item.MsgType == 5) {
                console.log("video message");
            }

            item.Login_ID = this.userInfo.User_ID;

            let wait = true;

            if (addLocal) {
                if (item.Receive_ID == 37) {
                    console.log("oops: 37");
                    console.log(item);
                }
                wait = JsBridge.sendRequest("message.add", item);
            }

            $.when(wait).then(() => {
                if (item.Send_ID == '0') {
                    this._notifySysMessage(this._processSysMessage(item));
                } else {
                    this._addMessage(item).then(m => {
                        this.notifyMessage(m.id);
                    });
                }
            });

        });
    }

    saveLocalMessages() {
        return JsBridge.sendRequest("message.flush", {LoginID: this.userInfo.User_ID});
    }

    // 生成一个消息对象
    _genMessage(sender, receiver, content) {
      if (receiver.User_ID) {
        return {
          ClientCode: this.ClientCode,
          ClientMessage_ID: this.ClientMessage_ID,
          IsDel: '0',
          IsRead: '0',
          IsShow: '1',
          LocalPath: content.LocalPath || '',
          Login_ID: sender.User_ID,
          Message_ID: '-1',
          MsgContent: content.content || '',
          MsgType: content.type,
          MsgUrl: content.MsgUrl || '',
          ReceiveName: receiver.UserName,
          Receive_ID: receiver.User_ID,
          SendDate: moment().format('YYYY/M/D HH:mm:ss'),
          SendName: sender.UserName,
          Send_ID: sender.User_ID,
          Send_ID2: '',
          needUpload: content.needUpload
        }
      } else {
        return {
          ClientCode: this.ClientCode,
          ClientMessage_ID: this.ClientMessage_ID,
          IsDel: '0',
          IsRead: '0',
          IsShow: '1',
          LocalPath: content.LocalPath || '',
          Login_ID: sender.User_ID,
          Message_ID: '-1',
          MsgContent: content.content || '',
          MsgType: content.type,
          MsgUrl: content.MsgUrl || '',
          ReceiveName: receiver.GroupName,
          Receive_ID: -receiver.Group_ID,
          SendDate: moment().format('YYYY/M/D HH:mm:ss'),
          SendName: sender.UserName,
          Send_ID: sender.User_ID,
          Send_ID2: '',
          needUpload: content.needUpload
        }
      }

    }

    _sendMessage(userId, userName, content) {
//  	alert('msgid+1-------------------' + this.ClientMessage_ID)
        let result = Api.get("/BasePlate/Interface/IInterfaceJson.asmx/Message_Send", {
            User_ID: this.userInfo.User_ID,
            SessionID: this.userInfo.SessionID,
            UserName: this.userInfo.UserName,
            Other_ID: userId,
            OtherName: userName,
            Content: content,
            ClientMessage_ID: this.ClientMessage_ID,
            ClientCode: this.ClientCode,
            Unit_ID: this.userInfo.Unit_ID
        }).then(resp => {
       
            if (resp.Goodo.EID === "0") {

                let messageId = parseInt(resp.Goodo.Message_ID);

                if (messageId > 0) {
                    return messageId;
                } else { // 失败
                    // return this._sendMessage(userId, userName, content);
                    return null;
                }
            } else {
                return null;
            }
        });

        this.ClientMessage_ID++;
//		alert('msgid+1-------------------' + this.ClientMessage_ID)
        return result;
    }

    sendMessage(userId, userName, content) {
        return this._sendMessage(userId, userName, content);
    }

    _sendFile(userId, userName, content, progressUCB, progressDCB) {
        let result = Api.uploadFile("/BasePlate/Interface/IInterfaceJson.asmx/Message_SendFile", {
            User_ID: this.userInfo.User_ID,
            SessionID: this.userInfo.SessionID,
            UserName: this.userInfo.UserName,
            Other_ID: userId,
            OtherName: userName,
            MsgType: content.type,
            FileName: content.fileName,
            Base64Data: content.base64,
            ClientMessage_ID: this.ClientMessage_ID,
            ClientCode: this.ClientCode,
            Unit_ID: this.userInfo.Unit_ID
        }, progressUCB ? progressUCB : () => {}, progressDCB ? progressDCB : () => {}).then(resp => {
          if (resp.Goodo.EID === "0") {

              let messageId = parseInt(resp.Goodo.Message_ID);

              if (messageId > 0) {
                  return messageId;
              } else { // 失败
                  // return this._sendMessage(userId, userName, content);
                  return null;
              }
          } else {
              return null;
          }
        });

        this.ClientMessage_ID++;
	
        return result;
    }

    sendFile(userId, userName, content, up, down) {
        return this._sendFile(userId, userName, content, up, down);
    }

    getMainUnreadNum() {
        return $.when(Api.get('/EduPlate/MSGMail/InterfaceJson.asmx/OuterMailAddr_ListGet', {
            User_ID: userInfo.User_ID,
            SessionID: userInfo.SessionID
        }), Api.get('/EduPlate/MSGMail/InterfaceJson.asmx/Receive_ClassifyGetList', {
            User_ID: userInfo.User_ID,
            SessionID: userInfo.SessionID
        })).then((resp1, resp2) => {
            let n1 = parseInt(resp.Goodo.R.Num), n2 = 0;

            resp2.Goodo.R.forEach(item => {
                n2 += parseInt(item.Num);
            });

            return n1 + n2;
        });
    }

    searchUser(keyword) {
        let deferred = $.Deferred(), groups = [], users = [], xhrs = [];

        xhrs.push(this._getDiscussGroups().then(discusssGroups => {
            if (discusssGroups) {
                discusssGroups.forEach(item => {
                    if (item.GroupName.indexOf(keyword) >= 0) {
                        groups.push(item);
                    }
                })
            }
        }));

        xhrs.push(JsBridge.sendRequest("user.search", {LoginID: this.userInfo.User_ID, keyword: keyword}).then(resp => {
            resp.data && resp.data.forEach(id => {
                if (id != this.userInfo.User_ID) {
                    xhrs.push(this._lookupUserOrDiscussGroup(id).then(u => {
                        users.push(u);
                    }));
                }
            });
        }));

        if (xhrs.length > 0) {
            $.when.apply($, xhrs).then(() => {
                deferred.resolve(users.concat(groups));
            });
        } else {
            deferred.resolve([]);
        }

        return deferred;
    }

    searchMessages(keyword) {
        let deferred = $.Deferred();

        JsBridge.sendRequest("message.search", { LoginID: this.userInfo.User_ID, keyword: keyword }).then(resp => {
            let xhrs = [];
            resp.data && resp.data.forEach(m => {
                let id = null;

                if (m.Send_ID == this.userInfo.User_ID) id = m.Receive_ID;
                else id = m.Send_ID;

                m.ts = moment(m.SendDate).unix();

                xhrs.push(this._lookupUserOrDiscussGroup(id).then(u => {
                    m.user = u;
                }));
            });

            if (xhrs.length > 0) {
                $.when.apply($, xhrs).then(() => {
                    resp.data.sort((a, b) => {
                        return a.ts - b.ts;
                    });

                    deferred.resolve(resp.data);
                });
            } else {
              deferred.resolve([]);
            }
        });

        return deferred;
    }

}

export default new ChatManager();
